home *** CD-ROM | disk | FTP | other *** search
- /*------------- INCLUDE FILES ----------------*/
-
- #include "common.h"
-
- /*------------- DEFINES ----------------*/
-
- /*------------ GLOBAL STRUCTURES -------------*/
-
- struct FileRequester *freq;
-
- /*------------ EXTERNAL STRUCTURES -------------*/
-
- extern struct IntuitionBase *IntuitionBase;
- extern struct GfxBase *GfxBase;
- extern struct ArpBase *ArpBase;
- extern struct ColorBase *ColorBase;
- extern struct IFFBase *IFFBase;
- extern struct ILBMBase *ILBMBase;
-
- extern struct Screen *scr;
- extern struct Window *win;
- extern struct ViewPort *viewport;
- extern struct RastPort *rastport;
- extern struct Screen *setscr;
- extern struct Window *setwin;
- extern struct RastPort *setrastport;
- extern struct Menu Menu1;
- extern struct Gadget ErrMessageGadg;
- extern struct Gadget RotationX;
- extern struct Gadget RotationY;
- extern struct Gadget RotationZ;
- extern struct Gadget EquationD;
- extern struct Gadget EquationZ;
-
- extern struct Border Border34;
- extern struct IntuiText IText93;
- #define BorderList Border34
- #define ITextList IText93
-
-
- /*------------ GLOBAL VARIABLES --------------*/
-
- TEXT dirfile[120];
- TEXT dirfile3DPL[120];
- TEXT colorfile[120];
- TEXT dataext[] = ".3DPL";
- BOOL fnokay = FALSE;
- BOOL titleon = FALSE;
- STRPTR InfixEq;
- AllPlotData *apd;
-
-
- /*----------- EXTERNAL VARIABLES -------------*/
-
- extern unsigned char SyntaxErr; /* For equation input */
- extern LONG plottype; /* How to plot the graph, see menuselect.h */
-
-
- /*----------- EXTERNAL FUNCTIONS -------------*/
-
- /* From openclose.c */
- extern VOID opendisplay(VOID);
- extern VOID openlibraries(VOID);
- extern VOID opendisplayset(VOID);
- extern LONG loaddisplay(STRPTR);
- extern LONG loadcolors(STRPTR);
- extern IFFP savecolors(STRPTR);
- extern VOID ChangeResolution(UBYTE);
- extern VOID finishup(LONG);
- /* From plot.c */
- extern VOID DrawGraph(VOID);
- extern VOID DrawContour(VOID);
- extern VOID SetLoresColors(VOID);
- extern VOID ChangePlotParameters(struct Screen *);
- /* From funceval.c */
- extern STRPTR Convert(STRPTR);
- /* From Data.c */
- extern AllPlotData *AllocAllPlotData(VOID);
- extern VOID Init3DPL(AllPlotData *);
- extern VOID SetGadgets(struct Gadget *, AllPlotData *);
- extern VOID PrintData(AllPlotData *);
-
- VOID handleerrmessage(struct Gadget *, STRPTR);
-
-
- /*----------- INTERNAL FUNCTIONS -------------*/
-
- BOOL handlefilename(VOID)
- {
- STRPTR temp;
-
- if(*(freq->fr_File) == 0) return FALSE; /* No filename */
-
- dirfile[0] = 0; /* make null string */
- strcpy(dirfile, freq->fr_Dir);
- TackOn(dirfile, freq->fr_File);
- strcpy(dirfile3DPL, dirfile);
- if(strlen(freq->fr_File) > strlen(dataext)) { /* Filename length > ext. name */
- temp = dirfile + strlen(dirfile) - strlen(dataext);
- if(strcmp(dataext, temp) == 0) { /* strings equal */
- *temp = 0; /* Cut off ext. on filename, dirfile3DPL will have ext. */
- }
- else {
- strcat(dirfile3DPL, dataext); /* add ext. */
- }
- }
- else {
- strcat(dirfile3DPL, dataext); /* add ext. */
- }
- return TRUE;
- } /* handlefilename */
-
-
- VOID handletemp(code)
- UWORD code;
- {
- WBenchToFront();
- printf("Menu num = %u\n", MENUNUM(code));
- printf("Item num = %u\n", ITEMNUM(code));
- printf("Sub num = %u\n\n", SUBNUM(code));
- Delay(150); /* 3 seconds */
- WBenchToBack();
-
- } /* handletemp */
-
-
- VOID handleproject(code)
- UWORD code;
- {
- LONG err;
-
- switch(ITEMNUM(code)) {
-
- case PROJECTNEW:
- { /* Start block */
- STRPTR string = ((struct StringInfo *)(EquationZ.SpecialInfo))->Buffer;
-
- Init3DPL(apd);
- SetGadgets(setwin->FirstGadget, apd);
- InfixEq = Convert(string);
- handleerrmessage(&EquationZ, string);
- } /* End block */
- break;
-
- case PROJECTOPEN:
- ScreenToFront(setscr);
-
- freq->fr_Hail = "LOAD FILE";
- freq->fr_Window = setwin;
- if (FileRequest(freq)) {
- fnokay = handlefilename();
- if(fnokay) {
- LONG submenu = SUBNUM(code);
-
- if( (submenu == OPENALL) || (submenu == OPENPICTURE) ) {
- err = loaddisplay(dirfile); /* Clears current display first */
- if(err) {
- printf("Error = %d\n", err);
- opendisplay(); /* Open previous display */
- }
- } /* if */
- if( (submenu == OPENALL) || (submenu == OPENSETTINGS) ) {
- err = Read3DPL(dirfile3DPL, apd);
- if(err) {
- printf("Error 3DPL = %d\n", err);
- }
- else {
- STRPTR string = ((struct StringInfo *)(EquationZ.SpecialInfo))->Buffer;
-
- SetGadgets(setwin->FirstGadget, apd);
- InfixEq = Convert(string);
- handleerrmessage(&EquationZ, string);
- }
- } /* if */
- } /* if */
-
- /* ScreenToFront(scr);
- ActivateWindow(win); */
- } /* if */
- break;
-
- case PROJECTSAVE:
- if(fnokay) { /* filename OK */
- LONG submenu = SUBNUM(code);
-
- if( (submenu == SAVEALL) || (submenu == SAVEPICTURE) ) {
- ShowTitle(scr, FALSE); /* Turn off for save */
- err = SaveBitMap(dirfile, rastport->BitMap,
- viewport->ColorMap->ColorTable, 1);
- if(titleon) ShowTitle(scr, TRUE); /* Turn back on */
- if(err == 0L) {
- err = IffError();
- printf("ERROR = %d\n", err);
- } /* if */
- } /* if */
- if( (submenu == SAVEALL) || (submenu == SAVESETTINGS) ) {
- err = Save3DPL(dirfile3DPL, apd);
- if(err) {
- printf("Error 3DPL = %d\n", err);
- }
- } /* if */
- } /* if */
-
- ScreenToFront(setscr);
- ActivateWindow(setwin);
- break;
-
- case PROJECTSAVEAS:
- ScreenToFront(setscr);
- freq->fr_Hail = "SAVE FILE";
- freq->fr_Window = setwin;
- if (FileRequest(freq)) {
- fnokay = handlefilename();
- if(fnokay) {
- LONG submenu = SUBNUM(code);
-
- if( (submenu == SAVEASALL) || (submenu == SAVEASPICTURE) ) {
- ShowTitle(scr, FALSE); /* Turn off for save */
- /*
- err = SaveBitMap(dirfile, rastport->BitMap,
- viewport->ColorMap->ColorTable, 1);
- */
- err = (LONG)SaveWindowToIFF(dirfile, win);
- if(titleon) ShowTitle(scr, TRUE); /* Turn back on */
- if(err == 0L) {
- err = IffError();
- printf("ERROR = %d\n", err);
- } /* if */
- } /* if */
- if( (submenu == SAVEASALL) || (submenu == SAVEASSETTINGS) ) {
- err = Save3DPL(dirfile3DPL, apd);
- if(err) {
- printf("Error 3DPL = %d\n", err);
- }
- } /* if */
- } /* if */
-
- } /* if */
- ActivateWindow(setwin);
- break;
-
- case PROJECTCOLOR:
- switch((UBYTE)SUBNUM(code)) {
- case COLORADJUST:
- ScreenToFront(scr);
- ActivateWindow(win);
- err = DoColor(NULL, scr);
- break;
- case COLORLOAD:
- { /* Start block */
- struct Window *fwin;
-
- Forbid();
- fwin = IntuitionBase->ActiveWindow;
- Permit();
- ScreenToFront(setscr);
- freq->fr_Hail = "LOAD COLORS";
- freq->fr_Window = setwin;
- if (FileRequest(freq)) {
- if(*(freq->fr_File) != 0) { /* Filename specified */
- colorfile[0] = 0; /* make null string */
- strcpy(colorfile, freq->fr_Dir);
- TackOn(colorfile, freq->fr_File);
- err = loadcolors(colorfile);
- if(err) {
- printf("Color load error = %d\n", err);
- }
- } /* if */
- } /* if */
- if(fwin = win) {
- ScreenToFront(scr);
- ActivateWindow(win);
- }
- else {
- ScreenToFront(setscr);
- ActivateWindow(setwin);
- }
- } /* End block */
- break;
- case COLORSAVE:
- ScreenToFront(setscr);
- freq->fr_Hail = "SAVE COLORS";
- freq->fr_Window = setwin;
- if (FileRequest(freq)) {
- if(*(freq->fr_File) != 0) { /* Filename specified */
- colorfile[0] = 0; /* make null string */
- strcpy(colorfile, freq->fr_Dir);
- TackOn(colorfile, freq->fr_File);
- err = savecolors(colorfile);
- if(err) {
- printf("Color save error = %d\n", err);
- }
- } /* if */
- } /* if */
- ActivateWindow(setwin);
- break;
- default:
- break;
- } /* switch */
- break;
-
- case PROJECTSCREEN:
- ChangeResolution((UBYTE)SUBNUM(code));
- ChangePlotParameters(scr);
- break;
-
- case PROJECTTITLE:
- if(SUBNUM(code) == TITLEON) {
- ShowTitle(scr, TRUE);
- titleon = TRUE;
- }
- else {
- ShowTitle(scr, FALSE);
- titleon = FALSE;
- }
- break;
-
- case PROJECTQUIT:
- finishup(0L);
- break;
-
- default:
- handletemp(code);
- break;
-
- } /* switch */
-
- } /* handleproject */
-
-
- VOID handlefunction(code)
- UWORD code;
- {
- switch(ITEMNUM(code)) {
- case FUNCTIONPLOT:
- plottype = SUBNUM(code);
- ScreenToFront(scr);
- ActivateWindow(win);
- if(plottype == PLOTCONTOUR) {
- DrawContour();
- }
- else { /* PLOTNORMAL, PLOTHIDDEN, PLOTFILLED */
- DrawGraph();
- }
- break;
- case FUNCTIONSETTINGS:
- ScreenToFront(setscr);
- ActivateWindow(setwin);
- break;
- case FUNCTIONGRAPH:
- ScreenToFront(scr);
- ActivateWindow(win);
- break;
- default:
- handletemp(code);
- break;
- } /* switch */
- } /* handlefunction */
-
-
- VOID handletext(code)
- UWORD code;
- {
- handletemp(code);
- }
-
-
- VOID handleerrmessage(gadget, EqBuf)
- struct Gadget *gadget; /* The equation gadget */
- STRPTR EqBuf; /* Pointer to equation string buffer */
- {
- STRPTR ErrMessage = ErrMessageGadg.GadgetText->IText;
- WORD ErrPosition = 0;
-
- strcpy(ErrMessage, " "); /* 40 */
- RefreshGList(&ErrMessageGadg, setwin, NULL, 1);
-
- /* ERROR STUFF */
-
- if (SyntaxErr) {
- if (SyntaxErr == STACKUNDERFLOW)
- strcpy(ErrMessage,"Stack underflow");
- else if (SyntaxErr == STACKOVERFLOW)
- strcpy(ErrMessage,"Stack overflow");
- else if (SyntaxErr == TOOMANYCONST)
- strcpy(ErrMessage,"Too many constants in function");
- else {
- ErrPosition = InfixEq - EqBuf;
-
- switch (SyntaxErr) {
- case MISPLACEDOP:
- strcpy(ErrMessage,"Misplaced operator");
- break;
- case ILLEGALCHAR:
- strcpy(ErrMessage,"Illegal character");
- break;
- case ILLEGALEXP:
- strcpy(ErrMessage,"Illegal exponent");
- break;
- case ILLEGALFUNC:
- strcpy(ErrMessage,"Illegal function");
- break;
- case MISSINGOP:
- strcpy(ErrMessage,"Missing operator");
- break;
- case MISSINGOPRP:
- strcpy(ErrMessage,"Missing operator or right parenthesis");
- break;
- case MISSINGLP:
- strcpy(ErrMessage,"Missing left parenthesis");
- break;
- case MISSINGRP:
- strcpy(ErrMessage,"Missing right parenthesis");
- break;
- case MISSINGPARM:
- strcpy(ErrMessage,"Missing parameter");
- break;
- case LONEDECIMAL:
- strcpy(ErrMessage,"Lone decimal point");
- break;
- case EXTRADECIMAL:
- strcpy(ErrMessage,"Extra decimal");
- break;
- case EXTRAE:
- strcpy(ErrMessage,"Extra E");
- break;
-
- } /* switch */
-
- } /* else */
-
- } /* if */
-
- else {
- strcpy(ErrMessage, "Acceptable");
- }
-
- ((struct StringInfo *)(gadget->SpecialInfo))->BufferPos = ErrPosition;
- RefreshGList(&ErrMessageGadg, setwin, NULL, 6);
-
- if(SyntaxErr)
- ActivateGadget(gadget, setwin, NULL); /* For correction */
-
- } /* handleerrmessage */
-
-
- VOID handleboolgadget(gadget)
- struct Gadget *gadget;
- {
- STRPTR gtext;
-
- switch(gadget->GadgetID) {
-
- case SURFACE:
- gtext = gadget->GadgetText->NextText->IText;
- switch(apd->pi.Surface) {
- case XANDY:
- apd->pi.Surface = XONLY;
- strcpy(gtext, "X Only ");
- break;
- case XONLY:
- apd->pi.Surface = YONLY;
- strcpy(gtext, "Y Only ");
- break;
- case YONLY:
- apd->pi.Surface = XANDY;
- strcpy(gtext, "X and Y");
- break;
- default:
- break;
- } /* switch */
- RefreshGList(gadget, setwin, NULL, 1);
- break;
-
- case AXESTYPE:
- gtext = gadget->GadgetText->NextText->IText;
- switch(apd->pi.AxesType) {
- case AXESTYPENONE:
- apd->pi.AxesType = AXESTYPESTAR;
- strcpy(gtext, "Star");
- break;
- case AXESTYPESTAR:
- apd->pi.AxesType = AXESTYPEBOX;
- strcpy(gtext, "Box ");
- break;
- case AXESTYPEBOX:
- apd->pi.AxesType = AXESTYPENONE;
- strcpy(gtext, "None");
- break;
- default:
- break;
- } /* switch */
- RefreshGList(gadget, setwin, NULL, 1);
- break;
-
- case SWAPXYZ:
- { /* begin block */
- WORD tempTopEdge;
-
- switch(apd->pi.RotationOrder) {
- case ROTATEXYZ: /* to XZY */
- /* New positions */
- tempTopEdge = RotationY.TopEdge;
- RotationY.TopEdge = RotationZ.TopEdge;
- RotationZ.TopEdge = tempTopEdge;
- /* Reorder gadgets in list */
- RotationY.NextGadget = RotationZ.NextGadget;
- RotationZ.NextGadget = &RotationY;
- RotationX.NextGadget = &RotationZ;
- break;
- case ROTATEXZY: /* to YXZ */
- /* New positions */
- tempTopEdge = RotationX.TopEdge;
- RotationX.TopEdge = RotationZ.TopEdge;
- RotationZ.TopEdge = RotationY.TopEdge;
- RotationY.TopEdge = tempTopEdge;
- /* Reorder gadgets in list */
- RotationZ.NextGadget = RotationY.NextGadget;
- RotationY.NextGadget = &RotationX;
- EquationD.NextGadget = &RotationY;
- break;
- case ROTATEYXZ: /* to YZX */
- /* New positions */
- tempTopEdge = RotationX.TopEdge;
- RotationX.TopEdge = RotationZ.TopEdge;
- RotationZ.TopEdge = tempTopEdge;
- /* Reorder gadgets in list */
- RotationX.NextGadget = RotationZ.NextGadget;
- RotationZ.NextGadget = &RotationX;
- RotationY.NextGadget = &RotationZ;
- break;
- case ROTATEYZX: /* to ZXY */
- /* New positions */
- tempTopEdge = RotationY.TopEdge;
- RotationY.TopEdge = RotationX.TopEdge;
- RotationX.TopEdge = RotationZ.TopEdge;
- RotationZ.TopEdge = tempTopEdge;
- /* Reorder gadgets in list */
- RotationY.NextGadget = RotationX.NextGadget;
- RotationX.NextGadget = &RotationY;
- EquationD.NextGadget = &RotationZ;
- break;
- case ROTATEZXY: /* to ZYX */
- /* New positions */
- tempTopEdge = RotationX.TopEdge;
- RotationX.TopEdge = RotationY.TopEdge;
- RotationY.TopEdge = tempTopEdge;
- /* Reorder gadgets in list */
- RotationX.NextGadget = RotationY.NextGadget;
- RotationY.NextGadget = &RotationX;
- RotationZ.NextGadget = &RotationY;
- break;
- case ROTATEZYX: /* to XYZ */
- /* New positions */
- tempTopEdge = RotationX.TopEdge;
- RotationX.TopEdge = RotationZ.TopEdge;
- RotationZ.TopEdge = tempTopEdge;
- /* Reorder gadgets in list */
- RotationZ.NextGadget = RotationX.NextGadget;
- RotationY.NextGadget = &RotationZ;
- RotationX.NextGadget = &RotationY;
- EquationD.NextGadget = &RotationX;
- break;
- default:
- break;
- } /* switch */
- RefreshGList(&EquationD, setwin, NULL, 4);
- apd->pi.RotationOrder = (++(apd->pi.RotationOrder)) % 6;
- } /* end block */
- break;
-
- default:
- break;
-
- } /* switch */
-
- } /* handleboolgadget */
-
-
- VOID handlestringgadget(gadget, next)
- struct Gadget *gadget;
- BOOL next;
- {
- STRPTR string = ((struct StringInfo *)(gadget->SpecialInfo))->Buffer;
- LONG longint = ((struct StringInfo *)(gadget->SpecialInfo))->LongInt;
- DOUBLE number;
-
- if( (gadget->Activation) & LONGINT ) { /* LONGINT */
-
- switch(gadget->GadgetID) {
- case ROTATIONX:
- apd->dd.RotationX = longint;
- break;
- case ROTATIONY:
- apd->dd.RotationY = longint;
- break;
- case ROTATIONZ:
- apd->dd.RotationZ = longint;
- break;
- case ORIGINX:
- apd->dd.OriginX = longint;
- break;
- case ORIGINY:
- apd->dd.OriginY = longint;
- break;
- default:
- break;
- } /* switch */
-
- } /* if */
-
- else { /* STRINGS */
-
- number = atof(string);
-
- switch(gadget->GadgetID) {
- case SIZINGPROJPLANE:
- apd->dd.ProjPlane = number;
- break;
- case SIZINGVIEWDIST:
- apd->dd.ViewDist = number;
- break;
- case SIZINGSCALE:
- apd->dd.Scale = number;
- break;
- case LINESPACINGX:
- apd->dd.LineSpacingX = number;
- break;
- case LINESPACINGY:
- apd->dd.LineSpacingY = number;
- break;
- case PLOTSPANXMIN:
- apd->dd.PlotXmin = number;
- break;
- case PLOTSPANXMAX:
- apd->dd.PlotXmax = number;
- break;
- case PLOTSPANYMIN:
- apd->dd.PlotYmin = number;
- break;
- case PLOTSPANYMAX:
- apd->dd.PlotYmax = number;
- break;
- case PLOTPRECISIONX:
- apd->dd.PlotPrecisionX = number;
- break;
- case PLOTPRECISIONY:
- apd->dd.PlotPrecisionY = number;
- break;
- case AXESSPANXMIN:
- apd->ad.AxesXmin = number;
- break;
- case AXESSPANXMAX:
- apd->ad.AxesXmax = number;
- break;
- case AXESSPANYMIN:
- apd->ad.AxesYmin = number;
- break;
- case AXESSPANYMAX:
- apd->ad.AxesYmax = number;
- break;
- case AXESSPANZMIN:
- apd->ad.AxesZmin = number;
- break;
- case AXESSPANZMAX:
- apd->ad.AxesZmax = number;
- break;
- case AXESPRECISION:
- apd->ad.AxesPrecision = number;
- break;
- case EQUATIONZ:
- InfixEq = Convert(string);
- strcpy(apd->ei.Equation, string);
- handleerrmessage(gadget, string);
- break;
- case SETTINGSNOTE:
- strcpy(apd->nt, string);
- break;
- default:
- break;
- } /* switch */
-
- if(gadget->GadgetID >= SIZINGPROJPLANE) { /* floating point */
- gcvt(number, 10, string);
- RefreshGList(gadget, setwin, NULL, 1);
- }
-
- } /* else */
-
- if(next == TRUE) { /* Next gadget if switch TRUE */
- BOOL exitflag;
-
- do {
- gadget = gadget->NextGadget;
-
- if(gadget == NULL) {
- exitflag = TRUE;
- }
- else if ( ((gadget->GadgetType) & STRGADGET) &&
- !((gadget->Flags) & GADGDISABLED) ) {
- ActivateGadget(gadget, setwin, NULL);
- exitflag = TRUE;
- }
- else {
- exitflag = FALSE;
- }
-
- } while(exitflag == FALSE);
-
- } /* if */
-
- } /* handlestringgadget */
-
-
- VOID handlemenu(code)
- UWORD code;
- {
- switch(MENUNUM(code)) {
- case MENUPROJECT:
- handleproject(code);
- break;
- case MENUFUNCTION:
- handlefunction(code);
- break;
- case MENUTEXT:
- handletext(code);
- break;
- default:
- break;
- } /* switch */
- } /* handlemenu */
-
-
- /*---------------- MAIN PROGRAM ---------------*/
-
- VOID main()
- {
- struct IntuiMessage *message;
- struct MenuItem *item;
- struct Gadget *gadget;
- struct Gadget *curgadget = NULL;
- ULONG mclass;
- UWORD menunum;
-
- openlibraries();
- opendisplay();
- opendisplayset();
-
- apd = AllocAllPlotData();
- Init3DPL(apd);
- SetGadgets(setwin->FirstGadget, apd);
-
- freq = ArpAllocFreq(); /* Alloc FileRequester Structure */
-
- PrintIText(setrastport, &ITextList, 0, 0);
- DrawBorder(setrastport, &BorderList, 0, 0);
-
- SetLoresColors();
-
- InfixEq = Convert(apd->ei.Equation);
-
- #define CheckGadg(x) {if(x) {handlestringgadget(x, FALSE); x = NULL; }}
-
- FOREVER {
-
- Wait( (1 << win->UserPort->mp_SigBit) | (1 << setwin->UserPort->mp_SigBit) );
-
- while(message = (struct IntuiMessage *) GetMsg(setwin->UserPort)) {
- mclass = message->Class;
- menunum = message->Code;
- gadget = (struct Gadget *) message->IAddress;
- ReplyMsg((struct Message *)message);
-
- switch(mclass) {
- case MENUPICK:
- CheckGadg(curgadget);
- while(menunum != MENUNULL) {
- item = (struct MenuItem *)ItemAddress(&Menu1, menunum);
- handlemenu(menunum);
- menunum = item->NextSelect;
- } /* while */
- break;
-
- case GADGETDOWN:
- CheckGadg(curgadget);
- if(gadget->GadgetType & BOOLGADGET) /* Boolean */
- handleboolgadget(gadget);
- else
- curgadget = gadget; /* String */
- break;
-
- case GADGETUP: /* String */
- handlestringgadget(gadget, TRUE);
- break;
-
- case MOUSEBUTTONS:
- case INACTIVEWINDOW:
- CheckGadg(curgadget);
- break;
-
- default:
- break;
-
- } /* switch */
-
- } /* while */
-
- while(message = (struct IntuiMessage *) GetMsg(win->UserPort)) {
- mclass = message->Class;
- menunum = message->Code;
- ReplyMsg((struct Message *)message);
-
- switch(mclass) {
- case MENUPICK:
- while(menunum != MENUNULL) {
- item = (struct MenuItem *)ItemAddress(&Menu1, menunum);
- handlemenu(menunum);
- menunum = item->NextSelect;
- } /* while */
- break;
-
- default:
- break;
-
- } /* switch */
-
- } /* while */
-
- } /* FOREVER */
-
- } /* main */
-